#include "pch.h"
#include "hci.h"

#include <stdio.h>
#include <memory.h>
#include <string.h>

void print_event(uint8_t *event, uint8_t size)
{
	printf(_T("< "));

	switch (event[0]){
	case 0x03:
		printf(_T("Connection Complete (Status 0x%02X, Handle 0x%04X, "), event[2], *((uint16_t*)&event[3]));
		printf(_T("Address 0x%02X%02X%02X%02X%02X%02X, "), event[5], event[6], event[7], event[8], event[9], event[10]);
		printf(_T("Type 0x%02X, Encryption 0x%02X)\n"), event[11], event[12]);
		break;
	case 0x04:
		printf(_T("Connection Request (Address 0x%02X%02X%02X%02X%02X%02X, "), event[2], event[3], event[4], event[5], event[6], event[7]);
		printf(_T("Class 0x%02X%02X%02X, Type 0x%02X)\n"), event[8], event[9], event[10], event[11]);
		break;
	case 0x05:
		printf(_T("Disconnection Complete (Status 0x%02X, Handle 0x%04X, Reason 0x%02X)\n"), event[2], *((uint16_t*)&event[3]), event[5]);
		break;
	case 0x0E:
		printf(_T("Command Complete (NumPackets %d, OPCode 0x%04X, Returns 0x%02X)\n"), event[2], *((uint16_t*)&event[3]), event[5]);
		break;
	case 0x0F:
		printf(_T("Command Status (Status 0x%02X, NumPackets %d, OPCode 0x%04X)\n"), event[2], event[3], *((uint16_t*)&event[4]));
		break;
	case 0x12:
		printf(_T("Role Change (Status 0x%02X, "), event[2]);
		printf(_T("Address 0x%02X%02X%02X%02X%02X%02X, "), event[3], event[4], event[5], event[6], event[7], event[8]);
		printf(_T("New Role 0x%02X)\n"), event[9]);
		break;
	case 0x13:
		printf(_T("Number Of Completed Packets (Number 0x%02X, Handle 0x%04X, Packets 0x%04X)\n"), event[2], *((uint16_t*)&event[3]), *((uint16_t*)&event[5]));
		break;
	case 0x1B:
		printf(_T("Max Slots Change (Handle 0x%04X, Slots 0x%02X)\n"), *((uint16_t*)&event[2]), event[4]);
		break;
	case 0x20:
		printf(_T("Page Scan Repetion Mode Change (Address 0x%02X%02X%02X%02X%02X%02X, "), event[2], event[3], event[4], event[5], event[6], event[7]);
		printf(_T("Mode 0x%02X)\n"), event[8]);
		break;
	default:
		printf(_T("Event Start\n"));
		for (unsigned long i = 0; i < size; i++){
			printf(_T("0x%02X \n"), event[i]);
		}
		printf(_T("Event End\n"));
		break;
	}
}

void print_acl(uint8_t *acl, uint8_t size)
{
	uint16_t handle = *((uint16_t*)&acl[0]);
	handle &= 0x0FFF;

	printf(_T("acl handle 0x%04X < channel 0x%04X "), handle, *((uint16_t*)&acl[6]));

	switch (acl[8]){
	case 0x02:
		printf(_T("CONNECTION REQUEST identifier 0x%02X, PSM 0x%04X, CID 0x%04X\n"), acl[9], *((uint16_t*)&acl[12]), *((uint16_t*)&acl[14]));
		break;
	case 0x05:
		printf(_T("CONFIGURATION RESPONSE identifier 0x%02X, CID 0x%04X, result 0x%04X\n"), acl[9], *((uint16_t*)&acl[12]), *((uint16_t*)&acl[16]));
		break;

	default:
		printf(_T("Size %d\n"), size);
		for (uint8_t i = 8; i < size; i++){
			printf(_T("0x%02X \n"), acl[i]);
		}
		printf(_T("End\n"));
		break;
	}
}

void print_command(uint8_t *command, uint8_t size)
{
	printf(_T("> "));

	switch (*((uint16_t*)command))
	{
	case 0x0C03:
		printf(_T("Reset\n"));
		break;
	case 0x0C1A:
		printf(_T("Write Scan Enable 0x%02X\n"), command[3]);
		break;
	case 0x0409:
		printf(_T("Accept Connection Request "));
		printf(_T("(Address 0x%02X%02X%02X%02X%02X%02X, "), command[3], command[4], command[5], command[6], command[7], command[8]);
		printf(_T("Role 0x%02X)\n"), command[9]);
		break;
	default:
		printf(_T("Command Start\n"));
		for (unsigned long i = 0; i < size; i++){
			printf(_T("0x%2X \n"), command[i]);
		}
		printf(_T("Command End\n"));
		break;
	}
}